﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//添加命名空间,使用Graphics需要
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;

namespace Pencil
{
    //绘图枚举类型
    public enum DrawType
    {
        Stop = 0,
        Line = 1,
        Rectangle = 2,
        Circle = 3,
        Sketch = 4
    }
    //图形（shape）抽象方法
    public abstract class Shape
    {
        //类字段
        private int _penWidth = 10;
        private Color _penColor = Color.Red;

        //类属性
        public int _PenWidth
        {
            get { return _penWidth; }
            set { _penWidth = value; }
        }
        public Color _PenColor
        {
            get { return _penColor; }
            set { _penColor = value; }
        }
        //定义绘画的抽象方法,第二个参数为线性类型
        public abstract void Draw(Graphics g, DashStyle ds, double zoomRatio);
        //写入方法
        public abstract void Write(BinaryWriter bw);
        //读取方法
        public abstract void Read(BinaryReader br);
    }
    //直线子类
    public class Line : Shape
    { 
        //类字段
        private Point _p1;
        private Point _p2;
        //类属性
        public Point _P1
        {
            get { return _p1; }
            set { _p1 = value; }
        }
        public Point _P2
        {
            get { return _p2; }
            set { _p2 = value; }
        }
        //无参构造方法
        public Line()
        { 
        }
        public Line(Point p1, Point p2)
        {
            _p1 = p1;
            _p2 = p2;
        }
        //绘制图元方法
        public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
        {
            //创建画笔
            Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
            //设置画笔类型
            pen.DashStyle = ds;
            //获取缩放后的起点终点
            Point p1 = new Point((int)(_p1.X * zoomRatio), (int)(_p1.Y * zoomRatio));
            Point p2 = new Point((int)(_p2.X * zoomRatio), (int)(_p2.Y * zoomRatio));
            //绘制直线
            g.DrawLine(pen, p1, p2);
        }
        //写入方法
        public override void Write(BinaryWriter bw)
        {
            //写入线宽和颜色
            bw.Write(_PenWidth);
            bw.Write(_PenColor.ToArgb());
            //写入p1,p2点的坐标
            bw.Write(_p1.X); bw.Write(_p1.Y);
            bw.Write(_p2.X); bw.Write(_p2.Y);
        }
        //读取方法
        public override void Read(BinaryReader br)
        {
            //读出线宽和颜色
            _PenWidth = br.ReadInt32();
            _PenColor = Color.FromArgb(br.ReadInt32());
            //读出_p1,_p2的坐标
            _p1.X = br.ReadInt32();
            _p1.Y = br.ReadInt32();
            _p2.X = br.ReadInt32();
            _p2.Y = br.ReadInt32();
        }
    }
    //矩形子类
    public class Rectangle : Shape
    {
        //类字段
        private Point _p1;//对角两个坐标
        private Point _p2;
        //类属性
        public Point _P1
        {
            get { return _p1; }
            set { _p1 = value; }
        }
        public Point _P2
        {
            get { return _p2; }
            set { _p2 = value; }
        }
        //构造方法
        public Rectangle()
        { 
        }
        //构造方法2
        public Rectangle(Point p1, Point p2)
        {
            _p1 = p1;
            _p2 = p2;
        }
        //绘制图元
        public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
        {
            //创建画笔
            Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
            //设置画笔类型
            pen.DashStyle = ds;
            //获取缩放后的起点终点
            Point p1 = new Point((int)(_p1.X * zoomRatio), (int)(_p1.Y * zoomRatio));
            Point p2 = new Point((int)(_p2.X * zoomRatio), (int)(_p2.Y * zoomRatio));
            //获取矩形左上角
            Point leftTop = new Point();
            leftTop.X = (p1.X <= p2.X) ? p1.X : p2.X;
            leftTop.Y = (p1.Y <= p2.Y) ? p1.Y : p2.Y;
            //绘制矩形
            g.DrawRectangle(pen, leftTop.X, leftTop.Y, Math.Abs(p2.X - p1.X), Math.Abs(p2.Y - p1.Y));
        }
        //写入方法
        public override void Write(BinaryWriter bw)
        {
            //写入线宽和颜色
            bw.Write(_PenWidth);
            bw.Write(_PenColor.ToArgb());
            //写入p1,p2点的坐标
            bw.Write(_p1.X); bw.Write(_p1.Y);
            bw.Write(_p2.X); bw.Write(_p2.Y);
        }
        //读取方法
        public override void Read(BinaryReader br)
        {
            //读出线宽和颜色
            _PenWidth = br.ReadInt32();
            _PenColor = Color.FromArgb(br.ReadInt32());
            //读出_p1,_p2的坐标
            _p1.X = br.ReadInt32();
            _p1.Y = br.ReadInt32();
            _p2.X = br.ReadInt32();
            _p2.Y = br.ReadInt32();
        }
    }
    //圆子类
    public class Circle : Shape
    {
        private Point _pCenter;//圆的中心点
        private float _r;//圆的半径

        public Point _PCenter
        {
            get { return _pCenter; }
            set { _pCenter = value; }
        }
        public float _R
        {
            get { return _r; }
            set { _r = value; }
        }

        public Circle()
        { 
        }
        public Circle(Point pCenter, float r)
        {
            _pCenter = pCenter;
            _r = r;
        }
        //绘制圆
        public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
        {
            Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
            //设置画笔类型
            pen.DashStyle = ds;
            //获取缩放后的圆心点坐标
            Point pCenter = new Point((int)(_pCenter.X * zoomRatio), (int)(_pCenter.Y * zoomRatio));
            float r = (float)(_r * zoomRatio);
            g.DrawEllipse(pen, pCenter.X - r, pCenter.Y - r, r * 2, r * 2);
        }
        //写入方法
        public override void Write(BinaryWriter bw)
        {
            //写入线宽和颜色
            bw.Write(_PenWidth);
            bw.Write(_PenColor.ToArgb());
            //写入圆心和半径
            bw.Write(_pCenter.X); 
            bw.Write(_pCenter.Y);
            bw.Write(_r);
        }
        //读取方法
        public override void Read(BinaryReader br)
        {
            //读出线宽和颜色
            _PenWidth = br.ReadInt32();
            _PenColor = Color.FromArgb(br.ReadInt32());
            //读出圆心和半径
            _pCenter.X = br.ReadInt32();
            _pCenter.Y = br.ReadInt32();
            _r = br.ReadSingle();
        }
    }
    //草图子类
    public class Sketch : Shape
    { 
        //类字段
        private List<Point> _pointList = new List<Point>();//草图的所有点
        
        //类属性
        public List<Point> _PointList
        {
            get { return _pointList; }
            set { _pointList = value; }
        }

        //构造方法
        public Sketch()
        { 
        }
        //绘制图元方法
        public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
        {
            //创建画笔对象
            Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
            //设置画笔类型
            pen.DashStyle = ds;
            //设置画笔的线帽样式为圆头
            pen.StartCap = LineCap.Round;
            pen.EndCap = LineCap.Round;
            for (int i = 1; i <= _pointList.Count() - 1; i++)
            { 
                //获取缩放后的草图点坐标
                Point p1 = new Point((int)(_pointList[i - 1].X * zoomRatio), (int)(_pointList[i - 1].Y * zoomRatio));
                Point p2 = new Point((int)(_pointList[i].X * zoomRatio), (int)(_pointList[i].Y * zoomRatio));
                //绘制图元
                g.DrawLine(pen, p1, p2);
            }
        }
        //写入方法
        public override void Write(BinaryWriter binaryWriter)
        {
            //写入线宽和颜色
            binaryWriter.Write(_PenWidth);
            binaryWriter.Write(_PenColor.ToArgb());
            //写入sketch的总点数
            binaryWriter.Write(_pointList.Count());
            //逐一写入sketch的点坐标
            foreach (Point tempPoint in _pointList)
            {
                binaryWriter.Write(tempPoint.X);
                binaryWriter.Write(tempPoint.Y);
            }
        }
        //读取方法
        public override void Read(BinaryReader binaryReader)
        {
            //清空_pointList
            _pointList.Clear();
            //读出线宽和颜色
            _PenWidth = binaryReader.ReadInt32();
            _PenColor = Color.FromArgb(binaryReader.ReadInt32());
            //读出总点数
            int pointCount = binaryReader.ReadInt32();
            //逐一读出坐标
            for (int i = 0; i <= pointCount - 1; i++)
            {
                int x = binaryReader.ReadInt32();
                int y = binaryReader.ReadInt32();
                Point point = new Point(x, y);
                _pointList.Add(point);
            }
        }
    }
}
